@gpc-cli/core 0.9.76 → 0.9.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -8925,7 +8925,7 @@ async function sha256File(filePath) {
8925
8925
  }
8926
8926
 
8927
8927
  // src/commands/image-sync.ts
8928
- import { readdir as readdir7 } from "fs/promises";
8928
+ import { readdir as readdir7, stat as stat10 } from "fs/promises";
8929
8929
  import { join as join12, extname as extname5 } from "path";
8930
8930
  import { PlayApiError } from "@gpc-cli/api";
8931
8931
  var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg"]);
@@ -8955,6 +8955,13 @@ async function scanLanguages(dir) {
8955
8955
  return [];
8956
8956
  }
8957
8957
  }
8958
+ async function dirExists(path) {
8959
+ try {
8960
+ return (await stat10(path)).isDirectory();
8961
+ } catch {
8962
+ return false;
8963
+ }
8964
+ }
8958
8965
  async function syncImages(client, packageName, dir, options) {
8959
8966
  const details = [];
8960
8967
  let uploaded = 0;
@@ -8992,23 +8999,59 @@ async function syncImages(client, packageName, dir, options) {
8992
8999
  const hash = await sha256File(join12(localDir, file));
8993
9000
  localHashes.set(file, hash);
8994
9001
  }
8995
- const localSha256Set = new Set(localHashes.values());
9002
+ const uploadLocal = async (file, reason) => {
9003
+ if (!options?.dryRun) {
9004
+ const filePath = join12(localDir, file);
9005
+ const check = await validateImage(filePath, imageType);
9006
+ if (!check.valid) {
9007
+ throw new GpcError(
9008
+ `Image validation failed for ${language}/${imageType}/${file}: ${check.errors.join("; ")}`,
9009
+ "IMAGE_INVALID",
9010
+ 2,
9011
+ "Check image dimensions, file size, and format."
9012
+ );
9013
+ }
9014
+ await client.images.upload(packageName, edit.id, language, imageType, filePath);
9015
+ }
9016
+ uploaded++;
9017
+ details.push({ language, imageType, file, action: "upload", reason });
9018
+ };
8996
9019
  if (options?.delete) {
8997
- for (const img of remoteImages) {
8998
- if (!localSha256Set.has(img.sha256.toLowerCase())) {
8999
- if (!options?.dryRun) {
9000
- await client.images.delete(packageName, edit.id, language, imageType, img.id);
9001
- }
9002
- deleted++;
9020
+ if (localFiles.length === 0 && remoteImages.length > 0 && !await dirExists(localDir)) {
9021
+ for (const img of remoteImages) {
9003
9022
  details.push({
9004
9023
  language,
9005
9024
  imageType,
9006
9025
  file: img.id,
9007
- action: "delete",
9008
- reason: "not in local"
9026
+ action: "skip",
9027
+ reason: "no local directory; remote left untouched"
9009
9028
  });
9010
9029
  }
9030
+ continue;
9011
9031
  }
9032
+ const localSeq = localFiles.map((file) => localHashes.get(file));
9033
+ const remoteSeq = remoteImages.map((img) => img.sha256.toLowerCase());
9034
+ const inOrder = localSeq.length === remoteSeq.length && localSeq.every((hash, i) => hash === remoteSeq[i]);
9035
+ if (inOrder) {
9036
+ for (const file of localFiles) {
9037
+ skipped++;
9038
+ details.push({ language, imageType, file, action: "skip", reason: "already in order" });
9039
+ }
9040
+ continue;
9041
+ }
9042
+ if (remoteImages.length > 0) {
9043
+ if (!options?.dryRun) {
9044
+ await client.images.deleteAll(packageName, edit.id, language, imageType);
9045
+ }
9046
+ for (const img of remoteImages) {
9047
+ deleted++;
9048
+ details.push({ language, imageType, file: img.id, action: "delete", reason: "reordering" });
9049
+ }
9050
+ }
9051
+ for (const file of localFiles) {
9052
+ await uploadLocal(file, "reordering");
9053
+ }
9054
+ continue;
9012
9055
  }
9013
9056
  for (const file of localFiles) {
9014
9057
  const hash = localHashes.get(file);
@@ -9016,21 +9059,7 @@ async function syncImages(client, packageName, dir, options) {
9016
9059
  skipped++;
9017
9060
  details.push({ language, imageType, file, action: "skip", reason: "sha256 match" });
9018
9061
  } else {
9019
- if (!options?.dryRun) {
9020
- const filePath = join12(localDir, file);
9021
- const check = await validateImage(filePath, imageType);
9022
- if (!check.valid) {
9023
- throw new GpcError(
9024
- `Image validation failed for ${language}/${imageType}/${file}: ${check.errors.join("; ")}`,
9025
- "IMAGE_INVALID",
9026
- 2,
9027
- "Check image dimensions, file size, and format."
9028
- );
9029
- }
9030
- await client.images.upload(packageName, edit.id, language, imageType, filePath);
9031
- }
9032
- uploaded++;
9033
- details.push({ language, imageType, file, action: "upload", reason: "new or changed" });
9062
+ await uploadLocal(file, "new or changed");
9034
9063
  }
9035
9064
  }
9036
9065
  }